/**
 * @file main.c
 * @brief ADC demo for sync mode and polling mode.
 *
 * @copyright Copyright (c) 2021  Semidrive Semiconductor.
 *            All rights reserved.
 */


#include <types.h>
#include <string.h>
#include <debug.h>
#include <pinmux_cfg.h>
#include <sdrv_adc.h>
#include <sdrv_adc_chmux.h>
#include <scr_hw.h>
#include <sdrv_scr.h>
#include <reset_cfg.h>
#include <clock_cfg.h>
#include <irq.h>
#include <irq_num.h>
#include <regs_base.h>
#include <board.h>

#include <sdrv_gpio.h>  ///
#include <udelay/udelay.h>
#include <sdrv_flexcan.h>
#include <flexcan_cfg.h>
///flexcan
#define TX_MB_INDEX (USED_MB_FOR_FIFO)
#define TX_PADDING_VAL (0xA5)

static flexcan_handle_t g_flexcan_handle;

static uint8_t g_rxFifoDataBuf[8];
static flexcan_frame_t g_frameBuf;

static uint8_t send_data[8] = 
        {0,  1,  2,  3,  4,  5,  6,  7};

static void flexcan_transfer_callback(flexcan_handle_t *handle,
                                      flexcan_status_e status, uint32_t result,
                                      void *userData)
{

    flexcan_frame_t *buf = (flexcan_frame_t *)userData;

    switch (status) {
    case FLEXCAN_RX_IDLE:
        ssdk_printf(SSDK_NOTICE, "controller_id=%d mb_idx=%d recv:\r\n",
                    handle->controller_id, result);
        ssdk_printf(SSDK_NOTICE, "frame len=%d id=%#x\r\n", buf->length, buf->id);
        ssdk_printf(SSDK_NOTICE, "data:\r\n");
        for (uint8_t i = 0; i < buf->length; i++) {
            ssdk_printf(SSDK_NOTICE, "%x ", buf->dataBuffer[i]);
        }
        ssdk_printf(SSDK_NOTICE, "\r\n");
        break;

    case FLEXCAN_RX_FIFO_IDLE:
        ssdk_printf(SSDK_NOTICE, "controller_id=%d mb_idx=%d recv:\r\n",
                    handle->controller_id, result);
        ssdk_printf(SSDK_NOTICE, "frame len=%d id=%#x\r\n", buf->length, buf->id);
        ssdk_printf(SSDK_NOTICE, "data:\r\n");
        for (uint8_t i = 0; i < buf->length; i++) {
            ssdk_printf(SSDK_NOTICE, "%x ", buf->dataBuffer[i]);
        }
        ssdk_printf(SSDK_NOTICE, "\r\n");
        break;

    case FLEXCAN_TX_IDLE:
        ssdk_printf(SSDK_NOTICE, "controller_id=%d mb_idx=%d tx done\r\n",
                    handle->controller_id, result);
        ssdk_printf(SSDK_NOTICE, "SSDK E3 fifo Demo Success!\r\n");
        break;

    case FLEXCAN_WAKEUP_TIMEOUT:
        break;

    case FLEXCAN_WAKEUP_MATCH:
        break;

    case FLEXCAN_ERROR_STATUS:
        break;

    default:
        break;
    }
}

static void flexcan_config_rx_fifo(flexcan_handle_t *handle,
                                    flexcan_rx_fifo_config_t *config)
{
    flexcan_frame_t *rx_fifo_frame = &g_frameBuf;
    rx_fifo_frame->dataBuffer = &g_rxFifoDataBuf[0];

    flexcan_set_rx_fifo_config(handle, config);

    for (uint8_t i = 0; i < USED_MB_FOR_FIFO;
         i++) {
        flexcan_set_rx_individual_mask(handle, i, config->filter_tab[i].filter_mask);
    }

    /* rx by interrupt */
    flexcan_fifo_transfer_t Xfer = {rx_fifo_frame};
    flexcan_receive_fifo_nonblocking(handle, &Xfer);
}

static inline void flexcan_config_tx_mailbox(flexcan_handle_t *handle,
                                             uint8_t index)
{
    flexcan_set_tx_mb_config(handle, index, true);
}

static void flexcan_send_demo(flexcan_handle_t *handle, uint8_t tx_index)
{
    flexcan_frame_t frame = {.id = 0x327,
                             .length = 8,
                             .type = FLEXCAN_FrameTypeData,
                             .format = FLEXCAN_STANDARD_FRAME,
                             .dataBuffer = &send_data[0]};
    flexcan_mb_transfer_t xfer = {&frame, tx_index};

    if (flexcan_get_mb_state(handle, tx_index) == FLEXCAN_StateIdle) {
        flexcan_send_nonblocking(handle, &xfer, TX_PADDING_VAL);
    } else {
        ssdk_printf(SSDK_NOTICE,
                    "controller_id=%d mb%d is not available for send\r\n",
                    handle->controller_id, tx_index);
    }
}


/* ADC参考电压, 单位为mV. */
#define BOARD_ADC_REF_VOLT      3300

#define GPIO_C0_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_NEG, ADC3_CH5N_MUX_C0)
#define GPIO_C1_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_POS, ADC3_CH5P_MUX_C1)

#define GPIO_C2_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_NEG, ADC3_CH5P_MUX_C3)
#define GPIO_C3_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_POS, ADC2_CH5P_MUX_C3)

#define GPIO_C4_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_NEG, ADC3_CH5N_MUX_C4)
#define GPIO_C5_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_POS, ADC3_CH5P_MUX_C5)

#define GPIO_C6_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_NEG, ADC3_CH5N_MUX_C6)
#define GPIO_C7_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_POS, ADC3_CH5P_MUX_C7)

#define GPIO_C8_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_NEG, ADC3_CH5N_MUX_C8)
#define GPIO_C9_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_POS, ADC3_CH5P_MUX_C9)

#define GPIO_C10_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_NEG, ADC3_CH5N_MUX_C10)
#define GPIO_C11_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_POS, ADC3_CH5P_MUX_C11)

#define GPIO_C12_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_NEG, ADC3_CH5N_MUX_C12)
#define GPIO_C13_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_POS, ADC3_CH5P_MUX_C13)

#define GPIO_C14_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_NEG, ADC3_CH5N_MUX_C14)
#define GPIO_C15_CH_SEL     ADC_CH_SEL_TAISHAN(5, ADC_CH_POLAR_POS, ADC3_CH5P_MUX_C15)

#define ADC_DEV_TEST        sdrv_adc3

#define adc_log(...)        ssdk_printf(SSDK_INFO, __VA_ARGS__)

typedef enum {
    ADC_CH_C0 = 0,
    ADC_CH_C1,
    ADC_CH_C2,
    ADC_CH_C3,
    ADC_CH_C4,
    ADC_CH_C5,
    ADC_CH_C6,
    ADC_CH_C7,
    ADC_CH_C8,
    ADC_CH_C9,
    ADC_CH_C10,
    ADC_CH_C11,
    ADC_CH_C12,
    ADC_CH_C13,
    ADC_CH_C14,
    ADC_CH_C15,
    ADC_CH_NUM
} adc_ch_t;


typedef struct adc_sample {
    uint32_t adc_chn;
    int conv_avg;
    int conv_data[512];
    uint32_t sample_time;
    int adc_range_max;
    int adc_range_min;
} adc_sample_t;

static int adc_data_cnt;
static uint32_t adc_data[64];
static adc_sample_t adc_sample_data[ADC_CH_NUM];

void adc_sample_data_init(void)
{
    memset(adc_sample_data, 0, sizeof(adc_sample_data));

    adc_sample_data[ADC_CH_C0].adc_chn = GPIO_C0_CH_SEL;
    adc_sample_data[ADC_CH_C0].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C0].adc_range_min = 0;

    adc_sample_data[ADC_CH_C1].adc_chn = GPIO_C1_CH_SEL;
    adc_sample_data[ADC_CH_C1].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C1].adc_range_min = 0;

    adc_sample_data[ADC_CH_C2].adc_chn = GPIO_C2_CH_SEL;
    adc_sample_data[ADC_CH_C2].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C2].adc_range_min = 0;

    adc_sample_data[ADC_CH_C3].adc_chn = GPIO_C3_CH_SEL;
    adc_sample_data[ADC_CH_C3].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C3].adc_range_min = 0;
    
    adc_sample_data[ADC_CH_C4].adc_chn = GPIO_C4_CH_SEL;
    adc_sample_data[ADC_CH_C4].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C4].adc_range_min = 0;

    adc_sample_data[ADC_CH_C5].adc_chn = GPIO_C5_CH_SEL;
    adc_sample_data[ADC_CH_C5].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C5].adc_range_min = 0;
 
    adc_sample_data[ADC_CH_C6].adc_chn = GPIO_C6_CH_SEL;
    adc_sample_data[ADC_CH_C6].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C6].adc_range_min = 0;    
 
    adc_sample_data[ADC_CH_C7].adc_chn = GPIO_C7_CH_SEL;
    adc_sample_data[ADC_CH_C7].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C7].adc_range_min = 0;      

    adc_sample_data[ADC_CH_C8].adc_chn = GPIO_C8_CH_SEL;
    adc_sample_data[ADC_CH_C8].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C8].adc_range_min = 0;          
    
    adc_sample_data[ADC_CH_C9].adc_chn = GPIO_C9_CH_SEL;
    adc_sample_data[ADC_CH_C9].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C9].adc_range_min = 0;              
    
    adc_sample_data[ADC_CH_C10].adc_chn = GPIO_C10_CH_SEL;
    adc_sample_data[ADC_CH_C10].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C10].adc_range_min = 0;
    
    adc_sample_data[ADC_CH_C11].adc_chn = GPIO_C11_CH_SEL;
    adc_sample_data[ADC_CH_C11].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C11].adc_range_min = 0;    

    adc_sample_data[ADC_CH_C12].adc_chn = GPIO_C12_CH_SEL;
    adc_sample_data[ADC_CH_C12].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C12].adc_range_min = 0;       
    
    adc_sample_data[ADC_CH_C13].adc_chn = GPIO_C13_CH_SEL;
    adc_sample_data[ADC_CH_C13].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C13].adc_range_min = 0;           
    
    adc_sample_data[ADC_CH_C14].adc_chn = GPIO_C14_CH_SEL;
    adc_sample_data[ADC_CH_C14].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C14].adc_range_min = 0;               
    
    adc_sample_data[ADC_CH_C15].adc_chn = GPIO_C15_CH_SEL;
    adc_sample_data[ADC_CH_C15].adc_range_max = 3300;
    adc_sample_data[ADC_CH_C15].adc_range_min = 0;                   
}

void adc_sample_data_check(void)
{
    uint32_t i;
    int ch, sum;

    for (ch = ADC_CH_C0; ch  < ADC_CH_NUM; ch++) {
        sum = 0;
        for (i = 0; i < adc_sample_data[ch].sample_time; i ++) {
            sum += adc_sample_data[ch].conv_data[i];
        }
        adc_sample_data[ch].conv_avg = sum/(int)adc_sample_data[ch].sample_time;
        adc_log("ch=%d, avg=%d\r\n", ch, adc_sample_data[ch].conv_avg);
        if ((adc_sample_data[ch].conv_avg > adc_sample_data[ch].adc_range_max)
                || (adc_sample_data[ch].conv_avg < adc_sample_data[ch].adc_range_min)) {
            ssdk_printf(SSDK_INFO, "SSDK E3 ADC Demo Failed!\r\n");
            return;
        }
        adc_sample_data[ch].sample_time = 0;
    }

    ssdk_printf(SSDK_INFO, "SSDK E3 ADC Demo Success!\r\n");
}

void print_adc_data(uint32_t adc_data)
{
    uint32_t adc_chnl;
    uint32_t conv_data;

    /* FIFO PACK32模式下，低12bit为ADC转换值，中间9bit为通道号amsel，高11bit为time stamp。 */
    conv_data = adc_data & 0xFFF;
    adc_chnl = (adc_data >> 12) & 0x1FF;

    switch (adc_chnl) {
    case GPIO_C0_CH_SEL:
        adc_log("C0 sample_val %d Volt=%dmV\r\n",
                conv_data,
                /* 计算单端模式的转换电压 */
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C0].conv_data[adc_sample_data[ADC_CH_C0].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C0].sample_time++;
        break;

    case GPIO_C1_CH_SEL:
        adc_log("C1 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C1].conv_data[adc_sample_data[ADC_CH_C1].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C1].sample_time++;
        break;

    case GPIO_C2_CH_SEL:
        adc_log("C2 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C2].conv_data[adc_sample_data[ADC_CH_C2].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C2].sample_time++;
        break;

    case GPIO_C3_CH_SEL:
        adc_log("C3 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C3].conv_data[adc_sample_data[ADC_CH_C3].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C3].sample_time++;
        break;
        
    case GPIO_C4_CH_SEL:
        adc_log("C4 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C4].conv_data[adc_sample_data[ADC_CH_C4].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C4].sample_time++;
        break;
    case GPIO_C5_CH_SEL:
        adc_log("C5 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C5].conv_data[adc_sample_data[ADC_CH_C5].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C5].sample_time++;
        break;
    case GPIO_C6_CH_SEL:
        adc_log("C6 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C6].conv_data[adc_sample_data[ADC_CH_C6].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C6].sample_time++;
        break;
    case GPIO_C7_CH_SEL:
        adc_log("C7 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C7].conv_data[adc_sample_data[ADC_CH_C7].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C7].sample_time++;
        break;
    case GPIO_C8_CH_SEL:
        adc_log("C8 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C8].conv_data[adc_sample_data[ADC_CH_C8].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C8].sample_time++;
        break;
    case GPIO_C9_CH_SEL:
        adc_log("C9 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C9].conv_data[adc_sample_data[ADC_CH_C9].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C9].sample_time++;

        break;
    case GPIO_C10_CH_SEL:
        adc_log("C10 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C10].conv_data[adc_sample_data[ADC_CH_C10].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C10].sample_time++;
        break;
    case GPIO_C11_CH_SEL:
        adc_log("C11 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C11].conv_data[adc_sample_data[ADC_CH_C11].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C11].sample_time++;        
        break;
    case GPIO_C12_CH_SEL:
        adc_log("C12 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C12].conv_data[adc_sample_data[ADC_CH_C12].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C12].sample_time++;        
        break;
    case GPIO_C13_CH_SEL:
        adc_log("C13 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C13].conv_data[adc_sample_data[ADC_CH_C13].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C13].sample_time++;        
        break;
    case GPIO_C14_CH_SEL:
        adc_log("C14 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C14].conv_data[adc_sample_data[ADC_CH_C14].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C14].sample_time++;        
        break;
    case GPIO_C15_CH_SEL:
        adc_log("C15 sample_val %d Volt=%dmV\r\n",
                conv_data,
                conv_data * BOARD_ADC_REF_VOLT / 4096);
        adc_sample_data[ADC_CH_C15].conv_data[adc_sample_data[ADC_CH_C15].sample_time]
                = conv_data * BOARD_ADC_REF_VOLT / 4096;
        adc_sample_data[ADC_CH_C15].sample_time++;        
        break;        
    default:
        adc_log("channel: %X, sample_val: %d, time stamp: %d\r\n",
                adc_chnl,
                conv_data,
                adc_data >> 21);
        break;
    }

    return;
}

void adc_sync_demo(void)
{
    ///配置采样时间 参考电压 单端差分模式
    sdrv_adc_ana_param_cfg_t ana_param[] = {            
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},               
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE},
        {SDRV_ADC_SAMPLE_TIME_10D5, SDRV_ADC_REF_VREFP1, SDRV_ADC_INPUT_SINGLE}
    };
    /* 根据repeat_cnt， rc0一个queue周期需要总的转换次数为2. */
    sdrv_adc_rc_entry_cfg_t rc0_entry_cfg[] = {
        {GPIO_C0_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C1_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C2_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C3_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C4_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C5_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C6_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C7_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C8_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C9_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C10_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C11_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C12_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C13_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C14_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2},
        {GPIO_C15_CH_SEL, 0, SDRV_ADC_RC_REPM_HW_TRG, 2}
    };

    sdrv_adc_rc_cfg_t   rc0_cfg = {
        /* 同步模式难以通过触发周期确保slot开始时正好有触发，
            所以设置terminal=compare=1，让RC一直处于触发状态。 */
        1, 1,
        /* q_start q_end q_cur对应于rc0_entry_cfg存放在rc entry中的起始位置、终止位置
           和rc首次触发的当前位置。 */
        0, 0, sizeof(rc0_entry_cfg) / sizeof(rc0_entry_cfg[0]) - 1,
        SDRV_ADC_RC_TMR_MODE_MASTER, SDRV_ADC_RC_TRG_MODE_HW, 1};
    
    /* 配置同步模式slot间隔最大值为50clock。ana_param中最长采样时间34.5clock，再加13.5clock，
       即转换时间最长为48clock。再加2clock余量。 */
    sdrv_adc_sync_cfg_t sync_cfg = {50, 0}; //max samctrl 5 (48 + 2);           ///转换时间间隔  时间间隔是恒定的还是可变的
    uint8_t cid_buf[32];
    int i;

    sdrv_adc_init(ADC_DEV_TEST, SDRV_ADC_CLK_DIV_MIN);

    /* 将ana_param依次配置到0~2位置上 */
    for (i = 0; i < sizeof(ana_param) / sizeof(ana_param[0]); i++) {
        sdrv_adc_ana_param_cfg(ADC_DEV_TEST, i, ana_param[i]);
    }

    /* 将rc0_entry_cfg依次配置到rc0的0位置上 */
    for (i = 0; i < sizeof(rc0_entry_cfg) / sizeof(rc0_entry_cfg[0]); i++) {
        sdrv_adc_rc_entry_cfg(ADC_DEV_TEST, 0, i, rc0_entry_cfg[i]);
    }

    /// 
    sdrv_adc_rc_cfg(ADC_DEV_TEST, 0, &rc0_cfg);
    ///sdrv_adc_rc_cfg(ADC_DEV_TEST, 1, &rc1_cfg);

    for(i = 0;i<32;i++)
    {
      cid_buf[i] = SDRV_ADC_SYNC_CID_RC0;               ///触发信号
    }
    /* RC1 repeat_cnt总数为32，需要占用32个slot。 */
    sdrv_adc_sync_cfg(ADC_DEV_TEST, sync_cfg, cid_buf, 32);

    /* 先启动触发再启动同步模式。以免slot启动后收不到触发信号，导致slot空转。*/
    sdrv_adc_rc_start_tmr(ADC_DEV_TEST, 0);
    ///sdrv_adc_rc_start_tmr(ADC_DEV_TEST, 1);
    sdrv_adc_sync_start(ADC_DEV_TEST);

    adc_data_cnt = 0;
    while (adc_data_cnt < sizeof(adc_data) / sizeof(adc_data[0])) {
        while (sdrv_adc_fifo_status(ADC_DEV_TEST) & SADC_SUB_FIFO_EMPTY);
        adc_data[adc_data_cnt++] = sdrv_adc_read_fifo(ADC_DEV_TEST);
    }

    ///sdrv_adc_stop(ADC_DEV_TEST, 1);

    ///adc_sample_data_init();
    for (i = 0; i < sizeof(adc_data) / sizeof(adc_data[0]); i++) {
        print_adc_data(adc_data[i]);
    }
    adc_sample_data_check();
    
    /* 清空FIFO残余数据 */
//    while (!(sdrv_adc_fifo_status(ADC_DEV_TEST) & SADC_SUB_FIFO_EMPTY)) {
//        sdrv_adc_read_fifo(ADC_DEV_TEST);
//    }

//    return;
}

void adc_check()
{
    uint32_t i;
    adc_data_cnt = 0;
    while (adc_data_cnt < sizeof(adc_data) / sizeof(adc_data[0])) {
        while (sdrv_adc_fifo_status(ADC_DEV_TEST) & SADC_SUB_FIFO_EMPTY);
        adc_data[adc_data_cnt++] = sdrv_adc_read_fifo(ADC_DEV_TEST);
    }

    ///sdrv_adc_stop(ADC_DEV_TEST, 1);

    ///adc_sample_data_init();
    for (i = 0; i < sizeof(adc_data) / sizeof(adc_data[0]); i++) {
        print_adc_data(adc_data[i]);
    }
    adc_sample_data_check();
}

static uint32_t DI_PIN[8] = {GPIO_H8,GPIO_H9,GPIO_H10,GPIO_H11,GPIO_H12,GPIO_H13,GPIO_S12,GPIO_L4};
static uint32_t DO_PIN[8] = {GPIO_H0,GPIO_L9,GPIO_H2,GPIO_H3,GPIO_H4,GPIO_H5,GPIO_F0,GPIO_H7};

static uint32_t UI_C_PIN[16] = {GPIO_B4,GPIO_B5,GPIO_B6,GPIO_B7,GPIO_B8,GPIO_B9,GPIO_B10,GPIO_B11,
GPIO_B12,GPIO_B13,GPIO_B14,GPIO_B15,GPIO_L5,GPIO_L6,GPIO_L7,GPIO_L8,
};
///HC595 数据更新
#define HC595_CS_PIN            GPIO_F2    
#define HC595_CLK_PIN           GPIO_F5
#define HC595_MOSI_PIN          GPIO_F4
volatile union 
{
  uint32_t V32;
  uint8_t v8[4];
}ADCPosValue;

void hc595_reflush(uint8_t *data,uint8_t len)
{
  uint8_t i8;
  sdrv_gpio_set_pin_output_level(HC595_CS_PIN, 0);
  
  for(i8 = 0;i8 < len;i8++)
  {
    if(data[i8] &0x80)
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 1);
    }
    else
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 0);
    }
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 0);
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 1);
    
    if(data[i8] & 0x40)
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 1);
    }
    else
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 0);
    }
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 0);
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 1);
    
    if(data[i8] &0x20)
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 1);
    }
    else
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 0);
    }
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 0);
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 1);
    
    if(data[i8] &0x10)
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 1);
    }
    else
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 0);
    }
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 0);
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 1);
    
    
    if(data[i8] &0x08)
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 1);
    }
    else
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 0);
    }
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 0);
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 1);
    
    if(data[i8] &0x04)
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 1);
    }
    else
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 0);
    }
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 0);
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 1);
    
    if(data[i8] &0x02)
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 1);
    }
    else
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 0);
    }
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 0);
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 1);
    
    if(data[i8] &0x01)
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 1);
    }
    else
    {
      sdrv_gpio_set_pin_output_level(HC595_MOSI_PIN, 0);
    }
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 0);
    sdrv_gpio_set_pin_output_level(HC595_CLK_PIN, 1);
  }
  sdrv_gpio_set_pin_output_level(HC595_CS_PIN, 1);
}


void adc_pos_set(uint32_t ch,uint32_t pos)
{
  uint32_t set,clr;
  uint32_t lch;
  uint32_t mask;
  lch = ch%32;
  switch(pos)
  {
  case 0:           ///电压档
    set = 2*lch;
    clr = 2*lch+1;
    mask = ~(1 << clr);       ///清除电流
    break;
  case 1:           ///电流档
    set = 2*lch+1;
    clr = 2*lch;
    mask = ~(1 << clr);       ///清除电压  
    break;
  }
  ADCPosValue.V32 &= mask;
  ADCPosValue.V32 |= 1 << set;   
}

int main(void)
{
    uint8_t i8;
    bool read_status;
    uint8_t tdata[4] = {0x00,0x00,0x00,0x00};   ///设置成电压档

    sdrv_scr_t scr_ctrl = {
        .base = APB_SCR_SF_BASE,
    };
    const scr_signal_t adc_scr[] = {
        SCR_SF_ANA_SF_CFG_APD_A_C0_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C1_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C2_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C3_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C4_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C5_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C6_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C7_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C8_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C9_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C10_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C11_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C12_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C13_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C14_CTRL_3_0,
        SCR_SF_ANA_SF_CFG_APD_A_C15_CTRL_3_0,
    };
    int i;

    sdrv_ckgen_init(&g_clock_config);
    board_reset_init();
    irq_initialize(VIC1_BASE, IRQ_MAX_INTR_NUM);
    sdrv_pinctrl_init(NUM_OF_CONFIGURED_PINS, g_pin_init_config);

    board_debug_console_init();

    /* 配置管脚相应scr，使得片外管脚信号与片内ADC电路导通。 */
    for (i = 0; i < sizeof(adc_scr) / sizeof(adc_scr[0]); i++) {
        /* set APD_A ctrl to 1 */
        scr_set(&scr_ctrl, &adc_scr[i], 1);
    }

#ifdef  TEST_WITH_ADC3
    printf("ADC3 actual clock rate %d Hz\n", sdrv_ckgen_get_rate(CLK_NODE(g_ckgen_ip_adc3)));
#elif   defined ( TEST_WITH_ADC2 )
    printf("ADC2 actual clock rate %d Hz\n", sdrv_ckgen_get_rate(CLK_NODE(g_ckgen_ip_adc2)));
#endif
    
    ///
    adc_sync_demo();
    
    ///设置电压电流采集档位
    for(uint8_t i8 =0;i8<16;i8++)
    {
      adc_pos_set(i8,0);
    }
    tdata[0] = ADCPosValue.v8[0];
    tdata[1] = ADCPosValue.v8[1];
    tdata[2] = ADCPosValue.v8[2];
    tdata[3] = ADCPosValue.v8[3];    
    hc595_reflush(tdata,4);

    ///flexcan
    /* initialize the FlexCAN handle. */
    flexcan_handle_t *handle = &g_flexcan_handle;
//    flexcan_create_handle(handle, FLEXCAN3, (void *)APB_CANFD3_BASE,
//                          CANFD3_CANFD_INTR_NUM, flexcan_transfer_callback,
//                          NULL);
    
//     flexcan_create_handle(handle, FLEXCAN4, (void *)APB_CANFD4_BASE,
//                          CANFD4_CANFD_INTR_NUM, flexcan_transfer_callback,
//                          NULL);

//     flexcan_create_handle(handle, FLEXCAN5, (void *)APB_CANFD5_BASE,
//                          CANFD5_CANFD_INTR_NUM, flexcan_transfer_callback,
//                          NULL);
    
//       flexcan_create_handle(handle, FLEXCAN6, (void *)APB_CANFD6_BASE,
//                        CANFD6_CANFD_INTR_NUM, flexcan_transfer_callback,
//                        NULL);
     
//         flexcan_create_handle(handle, FLEXCAN7, (void *)APB_CANFD7_BASE,
//                      CANFD7_CANFD_INTR_NUM, flexcan_transfer_callback,
//                      NULL);
         flexcan_create_handle(handle, FLEXCAN8, (void *)APB_CANFD8_BASE,
                  CANFD8_CANFD_INTR_NUM, flexcan_transfer_callback,
                  NULL);
    
    /* initialize flexCAN. */
    flexcan_init(handle, &g_flexcan_config);
    /* unfreeze the flexCAN by demo. */
    flexcan_freeze(handle, false);
    /* enable irq. */
    irq_attach(handle->irq_num, flexcan_irq_handler, handle);
    irq_enable(handle->irq_num);
        /* assign fifo only for rx. */
    flexcan_config_rx_fifo(handle, &flexcan_fifo_cfg);

    /* assign mailbox14-20 for tx. */
    for (uint8_t i = TX_MB_INDEX; i < (TX_MB_INDEX + TX_MAILBOX_NUM);
         i++) {
        flexcan_config_tx_mailbox(handle, i);
    }

    
    for (;;)
    {
      adc_check();
      for(i8 =0;i8<8;i8++)
      {
        read_status = sdrv_gpio_read_pin_input_level(DI_PIN[i8]);
        if(read_status)
        {
          sdrv_gpio_set_pin_output_level(DO_PIN[i8], 0);
        }
        else
        {
          sdrv_gpio_set_pin_output_level(DO_PIN[i8], 1);
        }
      }
      
      for(i8 = 0;i8 < 16;i8++)
      {
        read_status = sdrv_gpio_read_pin_input_level(UI_C_PIN[i8]);
        if(read_status)
        {
          ///sdrv_gpio_set_pin_output_level(DO_PIN[i8], 1);
        }
        else
        {
          ///sdrv_gpio_set_pin_output_level(DO_PIN[i8], 0);
        }
      }
      
      flexcan_send_demo(handle, TX_MB_INDEX);
      udelay(1000000);
    }
}
